package com.haredot.service.impl;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.haredot.config.JwtConfig;
import com.haredot.entity.Order;
import com.haredot.entity.User;
import com.haredot.entity.vo.OrderApplyVo;
import com.haredot.mapper.OrderMapper;
import com.haredot.mapper.UserMapper;
import com.haredot.result.R;
import com.haredot.service.UserService;
import com.haredot.utils.JwtUtils;
import com.haredot.utils.MD5Utils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private OrderMapper orderMapper ;

    @Override
    public R<?> loginSys(User user) {
        // 根据 手机号 查询 用户表信息
        User u = userMapper.selectOne(new QueryWrapper<User>().eq("tel", user.getTel()));

        if (u == null || !MD5Utils.md5(user.getPassword()).equals(u.getPassword())) {
            return R.fail().data(Map.of("invalid", "用户名或密码不正确"));
        }

        if (!u.getRole().equals(user.getRole())) {
            return R.fail().data(Map.of("invalid", "登录角色不正确"));
        }

        // 如果登录成功、则生成 JWT令牌
        Map<String, Object> stringObjectMap = JwtUtils.generatorJwtAccessToken(u);
        Map<String, Object> stringObjectMap1 = JwtUtils.generatorJwtRefreshToken(u);

        Map<String, Object> data = new HashMap<>();
        data.putAll(stringObjectMap);
        data.putAll(stringObjectMap1);
        data.put("uid", u.getId()) ;
        data.put("role", u.getRole()) ;
        return R.ok().data(data);
    }

    @Override
    public R<?> refreshToken(String refresh) {

        // 验证令牌真假
        try {
            DecodedJWT decodedJWT = JwtUtils.checkToken(refresh);
            // 获取 用户ID
            Long uid = Long.parseLong(decodedJWT.getSubject());
            // 获取 JWT 唯一标识
            byte[] bytes = Base64.getDecoder().decode(decodedJWT.getId().getBytes(StandardCharsets.UTF_8));
            String jwtId = new String(bytes, StandardCharsets.UTF_8);

            String[] split = jwtId.split(":");

            if (split.length != 4) {
                throw new Exception("令牌异常") ;
            }

            // 根据用户ID 查询用户
            User user = userMapper.selectById(uid);

            String md5Text = split[3];

            String text = jwtId.substring(0, jwtId.length() - md5Text.length()) + user.getPassword() + ":" + JwtConfig.SECURE_KEY ;
            if (!MD5Utils.md5(text).equals(md5Text)) {
                throw new Exception("令牌异常") ;
            }
            Map<String, Object> data = new HashMap<>();
            // 换取令牌
            Map<String, Object> stringObjectMap = JwtUtils.generatorJwtAccessToken(user);
            Map<String, Object> stringObjectMap1 = JwtUtils.generatorJwtRefreshToken(user);

            data.putAll(stringObjectMap);
            data.putAll(stringObjectMap1);

            return R.ok().data(data);

        } catch (Exception e) {
            return R.fail().data(Map.of("invalid", "令牌不正确或已过期"));
        }
    }

    @Override
    public R<?> saveUsr(User user) {

        // 判断手机号是否已被注册
        String tel = user.getTel();
        User u = userMapper.selectOne(new QueryWrapper<User>().eq("tel", tel));

        if (u != null) {
            return R.fail().data(Map.of("invalid", "该手机号已被注册"));
        }
        // 将密码 进行加密、并保存到表中
        String password = user.getPassword();
        user.setPassword(MD5Utils.md5(password));

        userMapper.insert(user);

        return R.ok().build();
    }

    @Override
    public R<?> queryTeachers() {

        List<User> list = userMapper.selectList(new QueryWrapper<User>().eq("role", 2));
        return R.ok().data(list);
    }

    @Override
    public R<?> queryCoffeeList(Long userId) {
        // 根据 userId 查询 角色
        User user = userMapper.selectById(userId);

        if (user == null || user.getRole() == 1) {
            return R.fail("审核人角色不正确").build();
        }
        // 查询 申请人、申请时间 、 订单ID
        List<OrderApplyVo> list = userMapper.queryCoffeeListByUserId(userId);
        return R.ok().data(list);
    }

    @Override
    public R<?> queryCoffeeDetail(Long cid) {
        OrderApplyVo orderApplyVo = userMapper.findCoffeeDetail(cid) ;
        return R.ok().data(orderApplyVo);
    }

    @Override
    public R<?> verifyCoffee(Long cid, Integer agree) {

        if (agree != 0 && agree != 2) {
            return R.fail("审核状态不正确").build();
        }
        // 设置 有效期
        Order order = orderMapper.selectById(cid);
        order.setState(agree);
        if (agree == 2) {
            order.setApplyTime(LocalDateTime.now());
            LocalDate localDate = LocalDate.now().plusDays(7);
            order.setEffectTime(localDate);
        }

        // 审核 订单
        int len = orderMapper.update(order, new UpdateWrapper<Order>()
                .eq("state", 1)
                .eq("id", cid));

        if (len != 1) {
            return R.fail("审核状态不正确").build();
        }

        return R.ok().build();
    }

    @Override
    public R<?> cancelCoffee(Long cid) {

        int len = orderMapper.delete(new QueryWrapper<Order>()
                    .eq("id", cid).ne("state", 2));

        if (len != 1) {
            return R.fail().build();
        }
        return R.ok().build();
    }
}
